---
title: Adding meta timestamps
description: Adding createdAt and updatedAt timestamps
keywords:
  - electrodb
  - docs
  - concepts
  - dynamodb
  - query
  - entity
  - attribute
  - schema
  - index
layout: ../../../layouts/MainLayout.astro
---

In this example we can easily create both `updatedAt` and `createdAt` attributes on our model. `createdAt` will use ElectroDB's `set` and `readOnly` attribute properties, while `updatedAt` will make use of `readOnly`, and `watch` with the "watchAll" syntax: `{watch: "*"}`. By supplying an asterisk, instead of an array of attribute names, attributes can be defined to watch _all_ changes to _all_ attributes.

Using `watch` in conjunction with `readOnly` is another powerful modeling technique. This combination allows you to model attributes that can only be modified via the model and not via the user. This is useful for attributes that need to be locked down and/or strictly calculated.

Notice that both `updatedAt` and `createdAt` use the `set` property without using its arguments. The `readOnly` prevents modification of an attributes on `update`, `patch`, and `upsert`. By discarding the arguments passed to `set`, the `createdAt` attribute becomes effectively locked down from user influence/manipulation.

Additionally, `updatedAt` and `createdAt` are `required` and have `default` options. The `required` option ensures that new items cannot be created without these properties, and that these properties cannot be deleted. Lastly, `default` option then has the typing implication that it becomes an optional property to provide on `create`, `patch` and `upsert` operations.

```typescript
{
  model: {
    entity: "transaction",
    service: "bank",
    version: "1"
  },
  attributes: {
    accountNumber: {
      type: "string"
    },
    transactionId: {
      type: "string"
    },
    description: {
      type: "string",
    },
    createdAt: {
      type: "number",
      readOnly: true,
      required: true,
      default: () => Date.now(),
      set: () => Date.now(),
    },
    updatedAt: {
      type: "number",
      watch: "*",
      required: true,
      default: () => Date.now(),
      set: () => Date.now(),
    }
  },
  indexes: {
    transactions: {
      pk: {
        field: "pk",
        composite: ["accountNumber"]
      },
      sk: {
        field: "sk",
        composite: ["transactionId"]
      }
    }
  }
}
```
